﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the Microsoft Public License (Ms-PL).
// See accompanying file License.txt or copy at http://mews.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Mews.Net.Nntp.Cache
{
    using System;
    using System.Data.SqlServerCe;
    using System.Diagnostics.CodeAnalysis;

    /// <summary>Provides the means to bulk-update articles.</summary>
    internal sealed class InboundArticleUpdater : IDisposable
    {
        private static readonly string[] hasAttachmentsColumn = new string[] { InboundArticleNames.HasAttachmentsColumn };
        private static readonly string[] isBeingWatchedColumns =
            new string[] { InboundArticleNames.ReceiveFullArticleColumn, InboundArticleNames.IsBeingWatchedColumn };

        private static readonly string[] isExpandedColumn = new string[] { InboundArticleNames.IsExpandedColumn };
        private static readonly string[] hasBeenReadColumn = new string[] { InboundArticleNames.HasBeenReadColumn };
        private readonly SqlCeCommand command;
        private readonly SqlCeResultSet resultSet;

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>See <see cref="IDisposable.Dispose"/>.</summary>
        [SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", Justification = "We *are* calling Dispose, CA bug?")]
        public void Dispose()
        {
            this.resultSet.Dispose();
            this.command.Dispose();
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        internal InboundArticleUpdater(SqlCeConnection connection)
        {
            using (var articleCommandGuard =
                ScopeGuard.Create(this.command = CommandHelper.Create(connection, InboundArticleNames.Table)))
            {
                this.resultSet = this.command.ExecuteResultSet(ResultSetOptions.Updatable);
                articleCommandGuard.Dismiss();
            }
        }

        internal void UpdateHasAttachments(InboundArticle article)
        {
            this.Update(article, hasAttachmentsColumn, article.HasAttachments);
        }

        internal void UpdateIsBeingWatched(InboundArticle article)
        {
            this.Update(
                article,
                isBeingWatchedColumns,
                (article.ReceiveStatus != ReceiveStatus.FullArticle) && article.IsBeingWatched,
                article.IsBeingWatched);
        }

        internal void UpdateIsExpanded(InboundArticle article)
        {
            this.Update(article, isExpandedColumn, article.IsExpanded);
        }

        internal void UpdateHasBeenRead(InboundArticle article)
        {
            this.Update(article, hasBeenReadColumn, article.HasBeenRead);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void Update(InboundArticle article, string[] columnNames, params object[] values)
        {
            this.resultSet.Update(new object[] { article.Group.Id, article.Number }, columnNames, values);
        }
    }
}
